package main

import (
	"encoding/json"
	"flag"
	"log/slog"
	"net/http"
	"strconv"
	"time"

	"dcs/collector"
	"dcs/util"
)

var (
	listenAddr = flag.String("addr", ":8080", "HTTP服务监听地址")
	maxConns   = flag.Int("max-conns", 35000, "最大并发连接数")
	queueSize  = flag.Int("queue-size", 50000, "任务队列大小")
	debug      = flag.Bool("debug", false, "启用调试模式")
)

func main() {
	// 解析命令行参数
	flag.Parse()

	// 初始化日志
	var logger *slog.Logger
	if *debug {
		logger = util.NewDebugLogger()
	} else {
		logger = util.NewInfoLogger()
	}
	logger.Info("Starting DCS SNMP collector",
		"listen_addr", *listenAddr,
		"max_concurrent_connections", *maxConns,
		"task_queue_size", *queueSize,
		"debug", *debug)

	// 创建工作池
	workerPool := util.NewWorkerPool(*maxConns, *queueSize, logger)
	defer workerPool.Shutdown()

	// 创建采集器
	c := collector.NewCollector(logger)

	// 注册HTTP处理函数
	http.HandleFunc("/snmp", func(w http.ResponseWriter, r *http.Request) {
		// 只允许POST方法
		if r.Method != http.MethodPost {
			http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
			return
		}

		// 解析请求
		var req collector.SNMPRequest
		decoder := json.NewDecoder(r.Body)
		if err := decoder.Decode(&req); err != nil {
			http.Error(w, "Invalid request body: "+err.Error(), http.StatusBadRequest)
			return
		}
		defer r.Body.Close()

		// 设置响应头
		w.Header().Set("Content-Type", "application/json")

		// 创建结果通道
		resultChan := make(chan *collector.SNMPResult, 1)

		// 创建任务
		task := &collectTask{
			req:        req,
			collector:  c,
			logger:     logger,
			resultChan: resultChan,
		}

		// 提交任务到工作池
		if !workerPool.Submit(task) {
			errMsg := "Too many requests, please try again later"
			logger.Warn(errMsg, "target", req.Target)
			w.WriteHeader(http.StatusTooManyRequests)
			json.NewEncoder(w).Encode(map[string]string{
				"error": errMsg,
			})
			return
		}

		// 等待结果（带超时）
		select {
		case result := <-resultChan:
			if result.Success {
				w.WriteHeader(http.StatusOK)
			} else {
				w.WriteHeader(http.StatusInternalServerError)
			}
			json.NewEncoder(w).Encode(result)
		case <-time.After(60 * time.Second):
			errMsg := "Request timeout"
			logger.Warn(errMsg, "target", req.Target)
			w.WriteHeader(http.StatusGatewayTimeout)
			json.NewEncoder(w).Encode(map[string]string{
				"error": errMsg,
			})
		}
	})

	// 健康检查接口
	http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(map[string]string{
			"status":  "healthy",
			"pending": strconv.Itoa(workerPool.PendingTasks()),
		})
	})

	// 启动HTTP服务
	logger.Info("HTTP server starting", "address", *listenAddr)
	if err := http.ListenAndServe(*listenAddr, nil); err != nil {
		logger.Error("HTTP server failed to start", "error", err)
		panic(err)
	}
}

// collectTask 实现util.Task接口
type collectTask struct {
	req        collector.SNMPRequest
	collector  *collector.Collector
	logger     *slog.Logger
	resultChan chan<- *collector.SNMPResult
}

// Execute 执行采集任务
func (t *collectTask) Execute() {
	t.logger.Debug("Executing SNMP task", "target", t.req.Target, "operation", t.req.Operation)
	result, err := t.collector.Collect(t.req)
	if err != nil {
		t.logger.Warn("SNMP task failed", "target", t.req.Target, "error", err)
	} else {
		t.logger.Debug("SNMP task completed", "target", t.req.Target, "duration", result.Duration)
	}
	t.resultChan <- result
}
